﻿using DesignPatterns.DecoratorPattern.Component;
using DesignPatterns.DecoratorPattern.ConcreteComponent;
using DesignPatterns.DecoratorPattern.ConcreteDecorator;
using DesignPatterns.FacadePattern.Concrete;
using DesignPatterns.FacadePattern.Facade;
using DesignPatterns.IteratorPattern.Aggregate;
using DesignPatterns.IteratorPattern.Iterator;
using DesignPatterns.ObserverPattern.Observer;
using DesignPatterns.ObserverPattern.Subject;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace DesignPatterns
{
    class Program
    {
        public static void Main(string[] args)
        {
            //StrategyPattern();
            //NullObjectPattern();
            //SingletonPattern();
            //Observer();
            //IteratorPattern();
            //DecoratorPattern();
            FacadePattern();

            Console.ReadKey();
        }

        #region Helper Methods

        public static void Client1()
        {
            Dough dough = new Dough();
            Sauce sauce = new Sauce("Tomato");
            Topping mushroom = new Topping("Mushrooms");
            Cheese mozzarella = new Cheese("Mozzarella");
            Oven oven = new Oven();

            PizzaFacade pizzaFacade = new PizzaFacade(dough, sauce, mushroom, mozzarella);
            pizzaFacade.MakePizza();
        }

        public static void Client2()
        {
            Dough dough = new Dough();
            Sauce sauce = new Sauce("Tomato");
            Topping mushroom = new Topping("Mushrooms");
            Cheese mozzarella = new Cheese("Mozzarella");
            Oven oven = new Oven();

            PizzaFacade pizzaFacade = new PizzaFacade(dough, sauce, mushroom, mozzarella);
            pizzaFacade.MakePizza();
        }

        public static void PrintUsers(IIterator iterate)
        {
            iterate.First();
            while (!iterate.IsDone())
            {
                Console.WriteLine(iterate.Next());
            }
        }

        #endregion

        #region Design Patterns

        public static void FacadePattern()
        {
            Client1();
            Client2();
        }

        public static void DecoratorPattern()
        {
            IceCream iceCream = new Chocolate();
            iceCream = new Sprinkle(iceCream);
            iceCream = new Fudge(iceCream);
            iceCream = new Sprinkle(iceCream);

            Console.WriteLine(iceCream.Cost());
        }

        
        public static void IteratorPattern()
        {
            ISocialNetworking fb = new Facebook();
            ISocialNetworking tw = new Twitter();

            IIterator fbIterator = fb.CreateIterator();
            IIterator twITerator = tw.CreateIterator();

            Console.WriteLine("Facebook: ");
            PrintUsers(fbIterator);

            Console.WriteLine("Twitter: ");
            PrintUsers(twITerator);
        }

        public static void Observer()
        {
            YouTubeChannel channel = new YouTubeChannel();

            ISubscriber Joey = new User();
            ISubscriber Alex = new User();
            ISubscriber Gai = new Moderator();

            channel.Subscribe(Joey);
            channel.Subscribe(Alex);
            channel.Subscribe(Gai);

            channel.NotifySubscribers();

            Console.WriteLine("Alex unsubscribed");
            channel.Unsubscribe(Alex);

            channel.NotifySubscribers();
        }

        public static void SingletonPattern()
        {
            Logger logger = Logger.GetInstance();
            logger.WriteToFile("Message to Write");
        }

        public static void NullObjectPattern()
        {
            IWeapon weapon = null;
            Character character = new Character();

            while (true)
            {
                Console.WriteLine("Choose a weapon (1 = Sword, 2 = Axe, 3 = Club)");
                string input = Console.ReadLine();

                switch (input)
                {
                    case "1":
                        weapon = new Sword();
                        break;
                    case "2":
                        weapon = new Axe();
                        break;
                    case "3":
                        weapon = new Club();
                        break;
                    default:
                        weapon = new Null();
                        break;
                }

                character.setWeapon(weapon);
                character.Attack();

            }
        }

        public static void StrategyPattern()
        {
            IWeapon weapon = null;
            Character character = new Character();

            while (true)
            {
                Console.WriteLine("Choose a weapon (1 = Sword, 2 = Axe, 3 = Club)");
                string input = Console.ReadLine();

                switch (input)
                {
                    case "1":
                        weapon = new Sword();
                        break;
                    case "2":
                        weapon = new Axe();
                        break;
                    case "3":
                        weapon = new Club();
                        break;
                }

                character.setWeapon(weapon);
                character.Attack();
            }
        }

        #endregion
    }
}
